﻿@page "/restStatistic"

@using Gurux.DLMS.AMI.Shared.DIs
@using Gurux.DLMS.AMI.Shared.Enums
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using Gurux.DLMS.AMI.Shared.DTOs
@using Gurux.DLMS.AMI.Shared.DTOs.Authentication
@using Gurux.DLMS.AMI.Shared.Rest
@using Microsoft.AspNetCore.SignalR.Client
@using Gurux.DLMS.AMI.Shared
@using Gurux.DLMS.AMI.Module
@using Gurux.DLMS.AMI.Client.Helpers

@attribute [Authorize(Roles = "Admin")]
@inject NavigationManager NavigationManager
@inject HttpClient Http
@inject IGXNotifier Notifier
@inject ConfirmBase Confirm
@implements IDisposable

<PageTitle>@Properties.Resources.Actions</PageTitle>

    <MenuControl RightCorner="true">
        <ChildContent>
            <MenuItem Text="@Properties.Resources.Clear" Icon="oi oi-trash" OnClick="@OnClear" />
        </ChildContent>
    </MenuControl>

    <GXTable @ref="table"
             Context="stat"
             ItemsProvider="@GetItems"
             SelectionMode="SelectionMode.None"
             ShowAllUsers="false"
             ShowRemoved="false">
        <FilterContent>
            <th>
            </th>
            <th>
                <!--Path -->
            </th>
            <th>
                <input class="form-control" placeholder="Filter by start time..."
                       type="datetime-local"
                       @onchange="@((ChangeEventArgs __e) => filter.Start = Convert.ToDateTime(__e.Value))" />
            </th>
            <th>
                <input class="form-control" placeholder="Filter by end time..."
                       type="datetime-local"
                       @onchange="@((ChangeEventArgs __e) => filter.End = Convert.ToDateTime(__e.Value))" />
            </th>
        </FilterContent>
        <HeaderContent>
            <th>@Properties.Resources.ExecutionTime</th>
        <Th Id="Path">@Properties.Resources.Path</Th>
            <Th Id="Start" SortMode="SortMode.Descending">@Properties.Resources.StartTime</Th>
            <Th Id="End">@Properties.Resources.Ready</Th>
        </HeaderContent>
        <ItemContent>
            <td>@GetTime(stat)</td>
        <td>@stat.Path</td>
        <td>@stat.Start</td>
        <td>@stat.End</td>
    </ItemContent>
</GXTable>
<br />
<Confirm @ref="ClearConfirmation"
         ConfirmationChanged="OnClearConfirmation"
         ConfirmationTitle=@Properties.Resources.ConfirmDataClear
         AllowDelete="false"
         OkTitle=@Properties.Resources.Clear
         ConfirmationMessage=@Properties.Resources.AreYouSureYouWantToClearLog>
</Confirm>

@code {
    /// <summary>
    /// Selected REST statistic ID.
    /// </summary>
    [Parameter]
    public Guid? Id { get; set; }

    /// <inheritdoc />
    public string Name
    {
        get
        {
            return Gurux.DLMS.AMI.Client.Properties.Resources.RESTStatistic;
        }
    }

    /// <inheritdoc />
    public Type? ConfigurationUI
    {
        get
        {
            return null;
        }
    }

    /// <inheritdoc />
    public string? Icon
    {
        get
        {
            return "oi oi-tablet";
        }
    }

    /// <summary>
    /// Amount of the REST statistics shown on the view.
    /// </summary>
    [Parameter]
    public int Count { get; set; } = 0;

    /// <summary>
    /// Is filter shown.
    /// </summary>
    [Parameter]
    public bool Filter { get; set; } = true;

    /// <summary>
    /// Is title shown.
    /// </summary>
    [Parameter]
    public bool Title { get; set; } = true;

    /// <summary>
    /// Reference to the table.
    /// </summary>
    private GXTable<GXRestStatistic>? table;

    /// <summary>
    /// Device action log filter.
    /// </summary>
    private GXRestStatistic filter = new GXRestStatistic();

    /// <summary>
    /// User is verified before REST statistics are cleared.
    /// </summary>
    protected ConfirmBase? ClearConfirmation;

    private int GetTime(GXRestStatistic item)
    {
        if (item.End == null || item.Start == null)
        {
            return 0;
        }
        return (int)(item.End.Value - item.Start.Value).TotalMilliseconds;
    }

    /// <summary>
    /// Update table.
    /// </summary>
    protected async Task Updated()
    {
        try
        {
            if (table != null)
            {
                await table.RefreshDataAsync(true);
            }
        }
        catch (Exception ex)
        {
            Notifier?.ProcessError(ex);
        }
    }

    protected override async Task OnInitializedAsync()
    {
        //Wait until table is loaded. Don't remove this or table is null and last settings are not available.
        await Task.Delay(1);
        try
        {
            if (Notifier == null)
            {
                throw new ArgumentException(Properties.Resources.InvalidNotifier);
            }
            Notifier.ProgressStart();
            Notifier.ClearStatus();
            Notifier.On<IEnumerable<GXRestStatistic>>(this, nameof(IGXHubEvents.RestStatisticAdd), async (statistics) =>
            {
                await Updated();
            });
            Notifier.On<IEnumerable<GXUser>?>(this, nameof(IGXHubEvents.RestStatisticClear), async (users) =>
            {
                await Updated();
            });
            Notifier.Clear();
            Notifier.UpdateButtons();
            if (table != null && Id != null)
            {
                //Get last selected item.
                table.Active = new GXRestStatistic() { Id = Id.Value };
            }
        }
        catch (AccessTokenNotAvailableException exception)
        {
            exception.Redirect();
        }
        catch (Exception ex)
        {
            Notifier?.ProcessError(ex);
        }
        finally
        {
            Notifier?.ProgressEnd();
        }
    }

    private async ValueTask<ItemsProviderResult<GXRestStatistic>> GetItems(GXItemsProviderRequest request)
    {
        //Don't clear status or error is lost.
        Notifier?.ProgressStart();
        try
        {
            ListRestStatistics req = new ListRestStatistics()
                {
                    Index = request.StartIndex,
                    Count = request.Count,
                    Filter = filter,
                    OrderBy = request.OrderBy,
                    Descending = request.Descending
                };
            if (Count != 0)
            {
                req.Count = Count;
            }
            var ret = await Http.PostAsJson<ListRestStatisticsResponse>("api/RestStatistic/List", req, request.CancellationToken);
            return new ItemsProviderResult<GXRestStatistic>(ret.Statistics, ret.Count);
        }
        catch (TaskCanceledException)
        {
            //Let the table component handle this.
            throw;
        }
        catch (Exception ex)
        {
            Notifier?.ProcessError(ex);
        }
        finally
        {
            Notifier?.ProgressEnd();
        }
        return default;
    }

    public void Dispose()
    {
        Notifier.RemoveListener(this);
    }

    /// <summary>
    /// Clear the REST statistics.
    /// </summary>

    public void OnClear()
    {
        Notifier?.ClearStatus();
        ClearConfirmation?.Show();
    }

    /// <summary>
    /// Clear the REST statistic list.
    /// </summary>
    public async Task OnClearConfirmation(ConfirmArgs args)
    {
        try
        {
            if (args.Confirm)
            {
                await Http.PostAsJson<ClearRestStatisticResponse>("api/RestStatistic/Clear", new ClearRestStatistic());
            }
        }
        catch (AccessTokenNotAvailableException exception)
        {
            exception.Redirect();
        }
        catch (Exception ex)
        {
            Notifier?.ProcessError(ex);
        }
    }
}
